package com.soup.util;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * Description: Protostuff 序列化工具类
 * </p>
 *
 * @author zhaoyi
 * @date 2019-01-02 16:57
 */
public final class SerializeUtil {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(SerializeUtil.class);

    private SerializeUtil() {
    }

    private static class SerializeData {
        private Object target;
    }

    /**
     * 序列化
     * 
     * @param object 序列化对象
     * @return byte数组
     */
    @SuppressWarnings("unchecked")
    public static byte[] serialize(Object object) {
        byte[] bytes = null;
        SerializeData serializeData = new SerializeData();
        serializeData.target = object;
        Class<SerializeData> serializeDataClass = (Class<SerializeData>) serializeData.getClass();
        LinkedBuffer linkedBuffer = LinkedBuffer.allocate(1024 * 4);
        try {
            Schema<SerializeData> schema = RuntimeSchema.getSchema(serializeDataClass);
            bytes = ProtostuffIOUtil.toByteArray(serializeData, schema, linkedBuffer);
        } catch (Exception e) {
            LOGGER.error("serialize object occur erro!", e);
        } finally {
            linkedBuffer.clear();
        }

        return bytes;
    }

    /**
     * 反序列化
     * 
     * @param data byte数组
     * @param <T> 对象
     * @return 序列化对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T deserialize(byte[] data) {
        T obj = null;
        try {
            Schema<SerializeData> schema = RuntimeSchema.getSchema(SerializeData.class);
            SerializeData serializeData = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(data, serializeData, schema);
            obj = (T) serializeData.target;
        } catch (Exception e) {
            LOGGER.error("deserialize bytes occur error!", e);
        }

        return obj;
    }
}
